#include <string.h>
#include <stdarg.h>
#include "Includes.h"
#include <stm32f10x.h>
#include "DRV_Usart.h"

/*
@说明：加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
*/
#pragma import(__use_no_semihosting)   
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 
}; 
FILE __stdout;
FILE __stdin;
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 

/*
 * Rewrite fputc for printf 
 * NOTE: IAR options->C/C++ compiler->preprocessor add symbal _DLIB_FILE_DESCRIPTOR
 */
int fputc(int ch, FILE  *f)
{
    while((UART4->SR&0X40)==0){;}
    UART4->DR = (u8) ch;
    //usart_send_data(&usart4_context, &ch, 1);
    return ch;
}

/*
** Rewrite fgetc function and make scanf function work
**/
int fgetc(FILE* file)
{
	//while(USART_GetFlagStatus(UART4,USART_FLAG_RXNE)==RESET);
	//return (int)USART_ReceiveData(UART4);
    uint8_t c;
    
	if(usart_receive_data(&usart4_context, &c, sizeof(c), 0)==0){
        return -1;
    };
	return c;
}
/*
** Rewrite _ttywrch function and make scanf function work
**/
void _ttywrch (int ch)
{
	ch = ch;
}
//4G
static uint8_t usart1_tx_buf[0];//DMA发送未使用txbuf
static uint8_t usart1_rx_buf[912];//交流桩最大208字节+15("\r\n+QIURC:xxx\r\n\r\n")+预留
static uint8_t usart1_dma_tx_buf[sizeof(usart1_tx_buf)/2];
static uint8_t usart1_dma_rx_buf[sizeof(usart1_rx_buf)/2];

static uint8_t usart2_tx_buf[16];
static uint8_t usart2_rx_buf[16];
//计量
static uint8_t usart3_tx_buf[0];//DMA发送未使用txbuf
static uint8_t usart3_rx_buf[128];
static uint8_t usart3_dma_tx_buf[sizeof(usart3_tx_buf)/2];
static uint8_t usart3_dma_rx_buf[sizeof(usart3_rx_buf)/2];
//调试口
static uint8_t usart4_tx_buf[128];
static uint8_t usart4_rx_buf[128];
 
 
static void usart1_config(void)
{
#if 0
  nvic_irq_enable(USART0_IRQn, 0, 1);
  rcu_periph_clock_enable(RCU_GPIOA);
  rcu_periph_clock_enable(RCU_USART0);
 
  /* connect port to USARTx_Tx */
  gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
 
  /* connect port to USARTx_Rx */
  gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
#else
    //DMA
    GPIO_InitTypeDef  GPIO_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;

	//NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel 				  = USART1_IRQn;  //串口中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;			 //抢占优先级6
	NVIC_InitStructure.NVIC_IRQChannelSubPriority		  = 0;			 //子优先级0
	NVIC_InitStructure.NVIC_IRQChannelCmd				  = ENABLE; 	 //IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);									 //初始化VIC寄存器

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,  ENABLE);   //使能GPIOC
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   //使能UART1

    //端口配置
    //PA9 -> UART1_TX
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;        //复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //速度50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //PA10 -> UART1_RX
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);

#endif	
}

static void usart1_dma_rxconfig(void)
{
    ///////////DMA接收/////////////////////
    DMA_InitTypeDef DMA_InitStructure;		

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	                            //DMA1时钟打开

    DMA_DeInit(usart1_context.dma_rxchannel); 
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&usart1_context.usart_periph->DR);		        //DR 寄存器地址 (0x40013804)
    DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)usart1_context.dma_rx_buf;	//DMA接收缓冲地址
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralSRC;			    //外设->内存
    DMA_InitStructure.DMA_BufferSize         = usart1_context.dma_rx_buf_size;		    //DMA缓冲大小
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;		    //dma 不自增
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;		        //内存自增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;	        //DMA 数据宽度
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;			    //DMA 内存宽度
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;				        //DMA 普通模式，不循环接收数据
    DMA_InitStructure.DMA_Priority           = DMA_Priority_High;                   //DMA 高优先级
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;				        //关闭内存到内存
    DMA_Init(usart1_context.dma_rxchannel, &DMA_InitStructure);

    DMA_ClearFlag(DMA1_FLAG_GL5);                   //清除DMA1所有标志
    USART_DMACmd(usart1_context.usart_periph, USART_DMAReq_Rx, ENABLE);	//开串口DMA2功能
    DMA_Cmd(usart1_context.dma_rxchannel, ENABLE);					//开DMA1_5通道
}

static void usart1_dma_txconfig(void)
{
    ///////////DMA发送/////////////////////    
    DMA_InitTypeDef DMA_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	                                //DMA1 时钟

    DMA_DeInit(usart1_context.dma_txchannel);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&usart1_context.usart_periph->DR);
    DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)usart1_context.dma_tx_buf;   
    DMA_InitStructure.DMA_BufferSize         = 0;							            //DMA缓冲大小
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;	                //内存到外设
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;               //DMA外设地址不自增
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;	                //DMA内存地址自增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;             //外设数据宽度
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;	                //DMA内存数据宽度
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;			                //不循环接收
    DMA_InitStructure.DMA_Priority           = DMA_Priority_VeryHigh;	                //高优先级
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;			                //关闭内存到内存模式
    DMA_Init(usart1_context.dma_txchannel, &DMA_InitStructure);

    DMA_ClearFlag(DMA1_FLAG_GL4);
    USART_DMACmd(usart1_context.usart_periph, USART_DMAReq_Tx, ENABLE);
    DMA_Cmd(usart1_context.dma_txchannel, DISABLE);

    //清除标志
    DMA_ClearFlag(DMA1_FLAG_GL4);
    DMA_ClearFlag(DMA1_FLAG_HT4);
    DMA_ClearFlag(DMA1_FLAG_TC4);
    DMA_ClearFlag(DMA1_FLAG_TE4);
}

static void usart2_config(void)
{
#if 0
  nvic_irq_enable(USART1_IRQn, 1, 1);
  rcu_periph_clock_enable(RCU_GPIOD);
  rcu_periph_clock_enable(RCU_USART1);
  
  rcu_periph_clock_enable(RCU_AF);
  gpio_pin_remap_config(GPIO_USART1_REMAP, ENABLE);
  
  
  /* connect port to USARTx_Tx */
  gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
 
  /* connect port to USARTx_Rx */
  gpio_init(GPIOD, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
#else
	
#endif
}
 
static void usart3_config(void)
{
#if 0
  nvic_irq_enable(UART3_IRQn, 1, 1);
  rcu_periph_clock_enable(RCU_GPIOC);
  rcu_periph_clock_enable(RCU_UART3);
 
  /* connect port to USARTx_Tx */
  gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
 
  /* connect port to USARTx_Rx */
  gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
#else
    GPIO_InitTypeDef  GPIO_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;

    //NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel                   = USART3_IRQn; //串口中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;           //抢占优先级6
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;           //子优先级0
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;      //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);                                     //初始化VIC寄存器
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);   //使能UART3
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,  ENABLE);   //使能GPIOB

    //端口配置
    //PB10 -> USART3_TX
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;        //复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //速度50MHz
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    //PB11 -> USART3_RX
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //浮空输入
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
#endif
}

static void usart3_dma_rxconfig(void)
{
    ///////////DMA接收/////////////////////
    DMA_InitTypeDef DMA_InitStructure;		

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	                            //DMA1时钟打开

    DMA_DeInit(usart3_context.dma_rxchannel); 
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&usart3_context.usart_periph->DR);		        //DR 寄存器地址 (0x40013804)
    DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)usart3_context.dma_rx_buf;	//DMA接收缓冲地址
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralSRC;			    //外设->内存
    DMA_InitStructure.DMA_BufferSize         = usart3_context.dma_rx_buf_size;		    //DMA缓冲大小
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;		    //dma 不自增
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;		        //内存自增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;	        //DMA 数据宽度
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;			    //DMA 内存宽度
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;				        //DMA 普通模式，不循环接收数据
    DMA_InitStructure.DMA_Priority           = DMA_Priority_High;                   //DMA 高优先级
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;				        //关闭内存到内存
    DMA_Init(usart3_context.dma_rxchannel, &DMA_InitStructure);

    DMA_ClearFlag(DMA1_FLAG_GL3);                   //清除DMA1所有标志
    USART_DMACmd(usart3_context.usart_periph, USART_DMAReq_Rx, ENABLE);	//开串口DMA2功能
    DMA_Cmd(usart3_context.dma_rxchannel, ENABLE);					//开DMA1_5通道
}

static void usart3_dma_txconfig(void)
{
    ///////////DMA发送/////////////////////    
    DMA_InitTypeDef DMA_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	                                //DMA1 时钟

    DMA_DeInit(usart3_context.dma_txchannel);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&usart3_context.usart_periph->DR);
    DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)usart3_context.dma_tx_buf;   
    DMA_InitStructure.DMA_BufferSize         = 0;							            //DMA缓冲大小
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;	                //内存到外设
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;               //DMA外设地址不自增
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;	                //DMA内存地址自增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;             //外设数据宽度
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;	                //DMA内存数据宽度
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;			                //不循环接收
    DMA_InitStructure.DMA_Priority           = DMA_Priority_VeryHigh;	                //高优先级
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;			                //关闭内存到内存模式
    DMA_Init(usart3_context.dma_txchannel, &DMA_InitStructure);

    DMA_ClearFlag(DMA1_FLAG_GL2);
    USART_DMACmd(usart3_context.usart_periph, USART_DMAReq_Tx, ENABLE);
    DMA_Cmd(usart3_context.dma_txchannel, DISABLE);

    //清除标志
    DMA_ClearFlag(DMA1_FLAG_GL2);
    DMA_ClearFlag(DMA1_FLAG_HT2);
    DMA_ClearFlag(DMA1_FLAG_TC2);
    DMA_ClearFlag(DMA1_FLAG_TE2);
}

static void usart4_config(void)
{
#if 0
  nvic_irq_enable(UART4_IRQn, 1, 1);
  rcu_periph_clock_enable(RCU_GPIOC);
  rcu_periph_clock_enable(RCU_GPIOD);
  rcu_periph_clock_enable(RCU_UART4);
 
  /* connect port to USARTx_Tx */
  gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
 
  /* connect port to USARTx_Rx */
  gpio_init(GPIOD, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
#else
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	//NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel 				  = UART4_IRQn;  //串口中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8;			 //抢占优先级8
	NVIC_InitStructure.NVIC_IRQChannelSubPriority		  = 0;			 //子优先级0
	NVIC_InitStructure.NVIC_IRQChannelCmd				  = ENABLE; 	 //IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);									 //初始化VIC寄存器
 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);   //使能GPIOC
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);   //使能UART4
 
	//端口配置
	//PC10 -> UART4_TX
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;        //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	    //速度50MHz
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	//PC11 -> UART4_RX
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //浮空输入
	GPIO_Init(GPIOC, &GPIO_InitStructure);
#endif
}
 
static void usart1_deconfig(void)
{
#if 0	
  gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
  nvic_irq_disable(USART0_IRQn);
  rcu_periph_clock_disable(RCU_GPIOA);
  rcu_periph_clock_disable(RCU_USART0);
#else
	
#endif
}

static void usart1_dma_deconfig(void)
{
    DMA_DeInit(usart1_context.dma_rxchannel); 
    DMA_DeInit(usart1_context.dma_txchannel); 
}

 
static void usart2_deconfig(void)
{

}
 
 
static void usart3_deconfig(void)
{

}

static void usart3_dma_deconfig(void)
{
    DMA_DeInit(usart3_context.dma_rxchannel); 
    DMA_DeInit(usart3_context.dma_txchannel); 
}

static void usart4_deconfig(void)
{

}

 
usart_context_t usart1_context = {
  USART1,
  DMA_WAY,
  DMA1_Channel5,
  DMA1_Channel4,
  usart1_tx_buf,
  sizeof(usart1_tx_buf),
  0,
  0,
  usart1_rx_buf,
  sizeof(usart1_rx_buf),
  0,
  0,
  0,
  usart1_dma_tx_buf,
  sizeof(usart1_dma_tx_buf),
  usart1_dma_rx_buf,
  sizeof(usart1_dma_rx_buf),
  usart1_config,
  usart1_deconfig,
  usart1_dma_rxconfig,
  usart1_dma_txconfig,
  usart1_dma_deconfig
};
 
 
usart_context_t usart2_context = {
  USART2,
  INT_WAY,
  NULL,
  NULL,
  usart2_tx_buf,
  sizeof(usart2_tx_buf),
  0,
  0,
  usart2_rx_buf,
  sizeof(usart2_rx_buf),
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  usart2_config,
  usart2_deconfig,
  NULL,
  NULL,
  NULL
};
 
usart_context_t usart3_context = {
  USART3,
  DMA_WAY,
  DMA1_Channel3,
  DMA1_Channel2,
  usart3_tx_buf,
  sizeof(usart3_tx_buf),
  0,
  0,
  usart3_rx_buf,
  sizeof(usart3_rx_buf),
  0,
  0,
  0,
  usart3_dma_tx_buf,
  sizeof(usart3_dma_tx_buf),
  usart3_dma_rx_buf,
  sizeof(usart3_dma_rx_buf),
  usart3_config,
  usart3_deconfig,
  usart3_dma_rxconfig,
  usart3_dma_txconfig,
  usart3_dma_deconfig
};
/*For debug and log*/
usart_context_t usart4_context = {
  UART4,
  INT_WAY,
  NULL,
  NULL,
  usart4_tx_buf,
  sizeof(usart4_tx_buf),
  0,
  0,
  usart4_rx_buf,
  sizeof(usart4_rx_buf),
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  usart4_config,
  usart4_deconfig,
  NULL,
  NULL,
  NULL
};
 
 
void usart_config_init(usart_context_t *pusart_context, uint32_t brate,uint32_t dbits,uint32_t cparity)
{
  pusart_context->config();
#if 0  
  /* USART configure */
  usart_deinit(pusart_context->usart_periph);
  usart_baudrate_set(pusart_context->usart_periph, baud_rate);
  usart_receive_config(pusart_context->usart_periph, USART_RECEIVE_ENABLE);
  usart_transmit_config(pusart_context->usart_periph, USART_TRANSMIT_ENABLE);
  usart_word_length_set(pusart_context->usart_periph, USART_WL_8BIT);
  usart_stop_bit_set(pusart_context->usart_periph, USART_STB_1BIT);
  usart_enable(pusart_context->usart_periph);
  
  usart_interrupt_enable(pusart_context->usart_periph, USART_INT_RBNE);
#else

//初始化设置
 USART_InitTypeDef USART_InitStructure;

 USART_DeInit(pusart_context->usart_periph);
 USART_InitStructure.USART_BaudRate 		   = brate;							 //波特率设置
 USART_InitStructure.USART_WordLength		   = dbits;			 //字长为8位数据格式
 USART_InitStructure.USART_StopBits 		   = USART_StopBits_1;				 //一个停止位
 USART_InitStructure.USART_Parity			   = cparity;				 //无奇偶校验位
 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
 USART_InitStructure.USART_Mode 			   = USART_Mode_Rx | USART_Mode_Tx;  //收发模式
 USART_Init(pusart_context->usart_periph, &USART_InitStructure);										 //初始化串口

 if(pusart_context->work_way == INT_WAY)
 {
     //USART_ITConfig(pusart_context->usart_periph, USART_IT_IDLE, ENABLE );	 //开空闲中断
     USART_ITConfig(pusart_context->usart_periph, USART_IT_RXNE, ENABLE );  //开接收中断
     USART_ITConfig(pusart_context->usart_periph, USART_IT_ERR,  ENABLE);	 //开错误中断
 }
 else if(pusart_context->work_way == DMA_WAY)
 {
     //开中断
     USART_ITConfig(pusart_context->usart_periph, USART_IT_IDLE, ENABLE ); //开空闲中断
     USART_ITConfig(pusart_context->usart_periph, USART_IT_ERR,  ENABLE);  //开错误中断
     
     //清标志位
     USART_ClearFlag(pusart_context->usart_periph, USART_FLAG_TC);
     USART_ClearFlag(pusart_context->usart_periph, USART_FLAG_RXNE);
     USART_ClearFlag(pusart_context->usart_periph, USART_FLAG_IDLE);
     USART_ClearFlag(pusart_context->usart_periph, USART_FLAG_ORE);

     if(pusart_context->dma_rxconfig) pusart_context->dma_rxconfig();
     if(pusart_context->dma_txconfig) pusart_context->dma_txconfig();
 }
 USART_Cmd(pusart_context->usart_periph, ENABLE);                        //使能串口

 //inition mutex,wangtao??
 if(pusart_context->work_way==DMA_WAY){
 pusart_context->rx_mux = xSemaphoreCreateBinary();
 if(pusart_context->rx_mux==NULL){
     if(pusart_context->usart_periph == USART3)
        printf("USART3 xSemaphoreCreateBinary\r\n");
     if(pusart_context->usart_periph == UART4)
        printf("USART4 xSemaphoreCreateBinary\r\n");
 }
 }
 //MUTEX_CREATE(pusart_context->rx_mux);
#endif	
}
 
void usart_config_deinit(usart_context_t *pusart_context)
{
#if 0	
  usart_disable(pusart_context->usart_periph);
  usart_deinit(pusart_context->usart_periph);
#else
  USART_Cmd(pusart_context->usart_periph, DISABLE);						 //去使能串口
  USART_DeInit(pusart_context->usart_periph);
#endif
  pusart_context->deconfig();
}
 
 
void usart_send_block(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count)
{
  const uint8_t *send_buf = (const uint8_t *)_send_buf;
  uint16_t i;
  
  for(i = 0; i < send_count; i++) {
    while(RESET == USART_GetITStatus(pusart_context->usart_periph, USART_FLAG_TXE));
    USART_SendData(pusart_context->usart_periph, (uint8_t)send_buf[i]);
  }
  while(RESET == USART_GetITStatus(pusart_context->usart_periph, USART_FLAG_TC));
}
 
/*
 * Usart send base on usart send interrupt 
 */
void usart_send_it(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count)
{
  const uint8_t *send_buf = (const uint8_t *)_send_buf;
  uint16_t i;

  if((pusart_context->tx_wr+send_count) % pusart_context->tx_buf_size == pusart_context->tx_rd)
    return;

  /*
   * Write send data to send buffer and use interrupt send data.
   * Wait buffer effective when send buffer is full. 
   */
  for(i = 0; i < send_count; i++) {      
    //while((pusart_context->tx_wr+1) % pusart_context->tx_buf_size == pusart_context->tx_rd);
    pusart_context->tx_buf[pusart_context->tx_wr++] = send_buf[i];     
    pusart_context->tx_wr %= pusart_context->tx_buf_size;
  }
  USART_ITConfig(pusart_context->usart_periph, USART_IT_TXE, ENABLE );  //开发送中断
}

void usart_send_dma(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count)
{
    //usart1 ec800
    if(pusart_context->dma_txchannel == DMA1_Channel4){
        //清标志位
        DMA_ClearFlag(DMA1_FLAG_TC4);               //传输完成中断
        DMA_ClearFlag(DMA1_FLAG_TE4);               //传输错误中断
    }
    //usart3 meter
    else if(pusart_context->dma_txchannel == DMA1_Channel2){
        DMA_ClearFlag(DMA1_FLAG_TC2);               //传输完成中断
        DMA_ClearFlag(DMA1_FLAG_TE2);               //传输错误中断
    }
    else{
        return;
    }
    DMA_Cmd(pusart_context->dma_txchannel, DISABLE);            //关DMA，重设置参数
    pusart_context->dma_txchannel->CMAR  = (u32)(_send_buf);      //内存地址
    pusart_context->dma_txchannel->CNDTR = send_count;              //重置"DMA"发送长度
    DMA_Cmd(pusart_context->dma_txchannel, ENABLE);             //开始发送，执行此指令后CRR的EN位置1
}

int usart_send_data(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count)
{
    if(pusart_context->work_way == INT_WAY)
        usart_send_it(pusart_context,_send_buf,send_count);
    else if(pusart_context->work_way == DMA_WAY)
        usart_send_dma(pusart_context,_send_buf,send_count);
    else if(pusart_context->work_way == BLOCK_WAY)
        usart_send_block(pusart_context,_send_buf,send_count);
    return send_count;
}

int usart_write_bytes(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count)
{
    return usart_send_data(pusart_context,_send_buf,send_count);
}

int uart_write_bytes(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count)
{
    return usart_send_data(pusart_context,_send_buf,send_count);
}

void usart_wait_sned_finished(usart_context_t *pusart_context)
{
  while(pusart_context->tx_wr != pusart_context->tx_rd);
  while(RESET == USART_GetITStatus(pusart_context->usart_periph, USART_FLAG_TC));
}
 
/*
 * read data from receive buffer
 */
int usart_receive_data(usart_context_t *pusart_context, void *_receive_buf, const int receive_count, uint16_t ticks_to_wait)
{
  uint8_t *receive_buf = (uint8_t *)_receive_buf;
  int i, receive_count_real;

  //wangtao rxmux
  if(pusart_context->work_way == DMA_WAY){
      //dma interup give
      if(xSemaphoreTake(pusart_context->rx_mux,(portTickType)ticks_to_wait) != pdTRUE) {
          return -1;
      }
  }
  /*
   * Read data from receive buffer. 
   * The buffer have data that received from usart.
   */
  for(i = 0, receive_count_real = 0; i < receive_count; i++) {
    if(pusart_context->rx_rd == pusart_context->rx_wr) {
      return receive_count_real;
    } else {
      receive_buf[i] = pusart_context->rx_buf[pusart_context->rx_rd++];
      pusart_context->rx_rd %= pusart_context->rx_buf_size;
      receive_count_real++;
    }
  }
  return receive_count_real;
}

int usart_read_bytes(usart_context_t *pusart_context, void *_receive_buf, const int receive_count, uint16_t ticks_to_wait)
{
    return usart_receive_data(pusart_context,_receive_buf,receive_count,ticks_to_wait);
}

int uart_read_bytes(usart_context_t *pusart_context, void *_receive_buf, const int receive_count, uint16_t ticks_to_wait)
{
    return usart_receive_data(pusart_context,_receive_buf,receive_count,ticks_to_wait);
}

 
static void usart_rbne_it(usart_context_t *pusart_context)
{
  pusart_context->rx_buf[pusart_context->rx_wr++] = USART_ReceiveData(pusart_context->usart_periph);
  pusart_context->rx_wr %= pusart_context->rx_buf_size;
 
  /*
   * overflow handle
   */
  if(pusart_context->rx_wr == pusart_context->rx_rd) {
    pusart_context->rx_rd++;
    pusart_context->rx_rd %= pusart_context->rx_buf_size;
  }
}
 
static void usart_tbe_it(usart_context_t *pusart_context)
{
  if(pusart_context->tx_rd != pusart_context->tx_wr) {
    USART_SendData(pusart_context->usart_periph, pusart_context->tx_buf[pusart_context->tx_rd++]);
    pusart_context->tx_rd %= pusart_context->tx_buf_size;
  } else {
    //usart_interrupt_disable(pusart_context->usart_periph, USART_INT_TBE);
    USART_ITConfig(pusart_context->usart_periph,USART_IT_TXE,DISABLE);
  }
}

int dma_recv_len=0;
int dma_remain=0;

static void usart_idle_it(usart_context_t *pusart_context, int dma_rx_remain_size)
{
  if(pusart_context->work_way == DMA_WAY){
    
    dma_recv_len = pusart_context->dma_rx_buf_size - dma_rx_remain_size;
    for(int i=0;i<dma_recv_len; i++){
        pusart_context->rx_buf[pusart_context->rx_wr++] = pusart_context->dma_rx_buf[i];
        pusart_context->rx_wr %= pusart_context->rx_buf_size;
    }
  /*
   * overflow handle
   */
  if(pusart_context->rx_wr == pusart_context->rx_rd) {
    pusart_context->rx_rd++;
    pusart_context->rx_rd %= pusart_context->rx_buf_size;
  }
  memset(pusart_context->dma_rx_buf,0,pusart_context->dma_rx_buf_size);
  pusart_context->dma_rxchannel->CMAR  = (uint32_t)pusart_context->dma_rx_buf;//切换下次缓冲的接收位置
  pusart_context->dma_rxchannel->CNDTR = pusart_context->dma_rx_buf_size;
  }
}

void usart_it(usart_context_t *pusart_context)
{
    BaseType_t taskWoken;

  if(pusart_context->work_way == INT_WAY){
      if(USART_GetITStatus(pusart_context->usart_periph, USART_IT_RXNE) == SET) {   
        //USART_ITConfig(pusart_context->usart_periph, USART_IT_RXNE, DISABLE);
        USART_ClearITPendingBit(pusart_context->usart_periph, USART_IT_RXNE);
        usart_rbne_it(pusart_context);
      //xSemaphoreGiveFromISR(pusart_context->rx_mux, &taskWoken);
      }
     
      if(USART_GetITStatus(pusart_context->usart_periph, USART_IT_TXE) == SET) {
        //USART_ITConfig(pusart_context->usart_periph, USART_IT_TXE, DISABLE);
        //USART_ClearITPendingBit(pusart_context->usart_periph, USART_IT_TXE);
        usart_tbe_it(pusart_context);
      }
     
      if(USART_GetITStatus(pusart_context->usart_periph, USART_IT_ORE_ER) == SET) {
        //USART_ITConfig(pusart_context->usart_periph, USART_IT_ORE_ER, DISABLE);
        USART_ClearITPendingBit(pusart_context->usart_periph, USART_IT_ORE_ER);
      }
  }
  else if(pusart_context->work_way == DMA_WAY){
      uint32_t  sr;
      sr = sr;
      
      if(USART_GetITStatus(pusart_context->usart_periph, USART_IT_TXE) != RESET)     //发送空
      {
        USART_ClearITPendingBit(pusart_context->usart_periph, USART_IT_TXE);
      }
      
      if(USART_GetITStatus(pusart_context->usart_periph, USART_IT_TC) != RESET)      //发送完成
      {
        USART_ClearITPendingBit(pusart_context->usart_periph, USART_IT_TC);
        USART_ITConfig(pusart_context->usart_periph, USART_IT_TC, DISABLE);
      }
      
      if(USART_GetITStatus(pusart_context->usart_periph, USART_IT_RXNE) != RESET)    //收到
      {       
        USART_ClearITPendingBit(pusart_context->usart_periph, USART_IT_RXNE);     //清接收中断标志
      }
      
      if(USART_GetITStatus(pusart_context->usart_periph, USART_IT_ORE) != RESET)    //溢出错误（移位寄存器中的数据需要转移到RDR中，但是RDR 中有数据未读）
      {
        //sr = USART_ReceiveData(pusart_context->usart_periph);
        //USART_ClearITPendingBit(pusart_context->usart_periph, USART_IT_ORE);
      }
      
      if(USART_GetITStatus(pusart_context->usart_periph, USART_IT_IDLE) != RESET)       //空闲
      {
          sr = USART_ReceiveData(pusart_context->usart_periph);                         //读一次RDR数据
          DMA_Cmd(pusart_context->dma_rxchannel, DISABLE);                        //关DMA接收通道
          USART_ClearITPendingBit(pusart_context->usart_periph, USART_IT_IDLE );        //清空闲中断

          //dma_recv_len=pusart_context->dma_rx_buf_size-DMA_GetCurrDataCounter(pusart_context->dma_rxchannel)+1;
          //dma_remain=DMA_GetCurrDataCounter(pusart_context->dma_rxchannel);
          usart_idle_it(pusart_context,DMA_GetCurrDataCounter(pusart_context->dma_rxchannel));
          xSemaphoreGiveFromISR(pusart_context->rx_mux, &taskWoken);
          DMA_Cmd(pusart_context->dma_rxchannel, ENABLE); //开接收
      }
      
      if(USART_GetITStatus(pusart_context->usart_periph ,USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//错误
      {
        sr = USART_ReceiveData(pusart_context->usart_periph);
        USART_ClearITPendingBit(pusart_context->usart_periph, USART_IT_PE | USART_IT_FE | USART_IT_NE);
      }
  }
}
 
 
void USART1_IRQHandler(void)
{
  usart_it(&usart1_context);
}
 
void USART2_IRQHandler(void)
{
  usart_it(&usart2_context);
}

void USART3_IRQHandler(void)
{
  usart_it(&usart3_context);
}
 
void UART4_IRQHandler(void)
{
    uint32_t ulReturn;

//#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真，则需要支持OS.
    ulReturn = taskENTER_CRITICAL_FROM_ISR();   
//#endif
  usart_it(&usart4_context);

//#if SYSTEM_SUPPORT_OS 	    //如果SYSTEM_SUPPORT_OS为真，则需要支持OS.
 	taskEXIT_CRITICAL_FROM_ISR(ulReturn);											 
//#endif

}
 
 
#include <stdarg.h>
#include <stdio.h>
 
/*
 * usart printf function
 */
void usart_printf(usart_context_t *pusart_context, char *arg, ...)  
{  
  char buf[256], len;  
 
  va_list vl;  
  __va_start(vl, arg);  
  len = vsprintf(buf, arg, vl);   
  __va_end(vl);  
 
  usart_send_it(pusart_context, buf, len);
} 
 
 
#include <DRV_Systick.h>
 
void u_tm_log(char *arg, ...)
{
  char buf[512];
  uint32_t s, ms, len , n;
  uint32_t tm = get_systick_ms();
  s = tm / 1000;
  ms = tm % 1000;
  
  n = sprintf(buf, "[%d.%03d] ", s, ms);
  
  va_list vl;  
  __va_start(vl, arg);  
  len = vsprintf(buf+n, arg, vl);   
  __va_end(vl);  
  len = len+n;
  usart_send_data(&usart4_context, buf, len);
}
 
void u_log(char *arg, ...)
{
  char buf[512];
  uint32_t len;
  
  va_list vl;  
  __va_start(vl, arg);  
  len = vsprintf(buf, arg, vl);   
  __va_end(vl);  
  usart_send_data(&usart4_context, buf, len);
}

void DBUG_PRINTF(char *arg, ...)
{
	char buf[512];
  uint32_t m, s, ms, len , n;
  uint32_t tm = get_systick_ms();
  s = tm / 1000;
	m =s / 60;
	s = s % 60;
  ms = tm % 1000;
  
  n = sprintf(buf, "[%d.%d.%03d] ", m, s, ms);
  
  va_list vl;  
  __va_start(vl, arg);  
  len = vsprintf(buf+n, arg, vl);   
  __va_end(vl);  
  len = len+n;
  usart_send_data(&usart4_context, buf, len);
}

/*
** printf through write reg
**/
int rprintf(char *msg, ...)
{
    va_list vl;
    char buffer[128]={0};
    
    va_start(vl,msg);
    vsnprintf(buffer,sizeof(buffer),msg,vl);
    va_end(vl);

    for(int i=0;i<strlen(buffer);i++)
    {
        UART4->DR = (u8) buffer[i];
        while((UART4->SR&0X40)==0){;}
    }
    return 0;
}


